package bdz.projects.lavender.opsm.main {
	import bdz.common.utils.Stats;
	import bdz.projects.lavender.opsm.ui.*;
	import bdz.projects.lavender.opsm.model.*;
	import bdz.common.model.*;
	import bdz.common.events.*;
	import bdz.projects.lavender.opsm.events.*;
	import bdz.projects.lavender.opsm.utils.EIHandler;
	import bdz.projects.lavender.opsm.utils.LoadChunker;
	import bdz.projects.lavender.opsm.vo.ProductVO;
	import com.bit101.components.Component;
	import com.bit101.components.PushButton;
	import flash.external.ExternalInterface;
	
	import com.greensock.*;
	import com.greensock.easing.*;
	import com.bit101.components.ComboBox;
	import com.bit101.components.HBox;
	
	import flash.display.*;
	import flash.events.*;
	import flash.text.Font;
	import flash.utils.*;
	/**
	 * ...
	 * @author ...
	 */
	public class OPSMProducts extends Sprite {
		
		private var proxyGrid:FlipGrid;
		private var displayGrid:DisplayGrid;
		private var productCollection:FlipCollection;
		private var xmlLoader:XMLLoader;
		private var detailedView:ProductDetailedView;
		private var env:AppEnvironment;
		private var tooltip:MovieClip;
		private var ei:EIHandler;
		private var chunk:LoadChunker;
		private var chunkResume:Number;
		private var waitTimeout:Number;
		private var popFilter:ComboBox;
		private var pageList:HBox;
		private var lastSelected:PushButton;
		private var pageClicks:Array;
		private var pageTruncated:Boolean = false;
		private var edgeLimit:Number = 2;
		private var pTreshold:Number = 20;
		private var edgeDrop:ComboBox;
		private var max:Number;
		private var ltotal:Number;
		private var preloader:MovieClip;
		private var pwait:Number;
		private var defaultSKU:String;
		private var fromWait:Boolean = false;
		private var compressed:Boolean = false;
		function OPSMProducts() {
			handleParameters();
			ei = EIHandler.getInstance();
			ei.createCallback("applyProductFilters", onApplyProductFilters);
			ei.createCallback("onTestFilter", onTestFilter);
			ei.createCallback("onTestPageChange", onTestPageChange);
			env = AppEnvironment.getEnv();
			env.addSetting("baseImageWidth", 360);
			env.addSetting("baseImageHeight", 180);
			env.addSetting("defaultImageScale", .33333);
			addEventListener(Event.ADDED_TO_STAGE, initializeComponent);
			//addChild(new Stats());
			chunk = new LoadChunker();
			chunk.treshold = .2; //40%
			chunk.addEventListener(GenericEvent.PROGRESS_COMPLETE, onFirstChunkComplete);
			chunk.addEventListener(GenericEvent.COMPLETE, onChunkCompleted);
			executeWaitingView();
			compressed = loaderInfo.parameters.compressed == "1" ? true : false;
		}
		private function onChunkCompleted(evt:GenericEvent):void {
			
		}
		private function onFirstChunkComplete(evt:GenericEvent):void {
			productCollection.executeDelayedDispatch();
			doneWaiting();
			//load rest of the images
			chunkResume = setTimeout(chunk.resume, 2000);
		}
		private function handleParameters():void {
			
		}
		private function createDataManagers():void {
			xmlLoader = new XMLLoader("onXMLLoaded");
			xmlLoader.addEventListener("onXMLLoaded", onDefinitionLoaded);
			xmlLoader.addEventListener(XMLLoaderEvent.FAULT, onDefinitionLoadError);
			xmlLoader.addEventListener(XMLLoaderEvent.IOFAULT, onDefinitionLoadError);
			xmlLoader.location = loaderInfo.parameters.source || "opsm_products_test.xml";
			xmlLoader.send(null, compressed);
		}
		private function onDefinitionLoadError(evt:XMLLoaderEvent):void { 
			
		}
		private function onDefinitionLoaded(evt:XMLLoaderEvent):void {
			
			productCollection.parseXML(new XML(evt.data), true);
			chunk.loadItems = productCollection;
			chunk.start();
		}
		private function onFlipGridDone(evt:FlipGridEvent):void {
			if (chunk.paused) {
				chunk.resume();
			}
		}
		private function onDisplayGenerating(evt:GenericEvent):void {
			executeWaitingView();
		}
		private function createUIElements():void {
			displayGrid = new DisplayGrid(env.getSetting("baseImageWidth"), env.getSetting("baseImageHeight"));
			displayGrid.dataProvider = productCollection;
			displayGrid.x = 23;
			displayGrid.y = 70;
			displayGrid.addEventListener(GenericEvent.GENERATED, onDisplayGridGenerated);
			displayGrid.addEventListener(GenericEvent.PROGRESS, onDisplayGenerating);
			displayGrid.addEventListener(GenericEvent.CLICKED, onItemClicked);
			displayGrid.addEventListener(GenericEvent.ROLL_OUT, onItemRolledOut);
			displayGrid.addEventListener(GenericEvent.ROLL_OVER, onItemRolledOver);
			addChild(displayGrid);
			
			
			proxyGrid = new FlipGrid(env.getSetting("baseImageWidth"), env.getSetting("baseImageHeight"));
			proxyGrid.x  = Math.ceil(displayGrid.x + 60);
			proxyGrid.y = Math.ceil(displayGrid.y + 30);
			proxyGrid.guide = displayGrid;
			proxyGrid.addEventListener(FlipGridEvent.FLIP_DONE, onFlipGridDone);
			addChild(proxyGrid);
			
			
			popFilter = new ComboBox(this, 28, 18, "SORT BY", ["PRICE HIGH - LOW", "PRICE LOW - HIGH", "LATEST LISTING"]);
			popFilter.width = 120;
			popFilter.addEventListener(Event.SELECT, onPopFilterChange);
			popFilter.numVisibleItems = 4;
			popFilter.visible = false;
			tooltip = new Tooltip();
			tooltip.visible = false
			tooltip.alpha = 0;
			tooltip.mouseEnabled = false;
			addChild(tooltip);
		}
		private function onPageClick(evt:Event):void {
			if(lastSelected){
				lastSelected.selected = false;
				lastSelected.enabled = true;
			}
			
			lastSelected = evt.target as PushButton;
			lastSelected.enabled = false;
			displayGrid.gotoPage(Number(lastSelected.label));
		}
		private function onEdgePageSelect(evt:Event):void {
			if(lastSelected){
				lastSelected.selected = false;
				lastSelected.enabled = true;
				lastSelected = null;
			}
			displayGrid.gotoPage(Number(edgeDrop.selectedItem));
		}
		private function createPages(current:Number, total:Number):void {
			var sx:Number = 0;
			var sy:Number = 0;
			if (ltotal == total) return;
			ltotal = total;
			
			if (total > pTreshold) {
				max = pTreshold - edgeLimit;
				pageTruncated = true;
			}else {
				max = total;
				pageTruncated = false;
			}
			if (pageList) {
				try {
					removeChild(pageList);
				}catch(e:Error){}
			}
			pageList = new HBox(this, 740, 625);
			pageList.spacing = 0;
			pageClicks = new Array();
			
			for (var i:Number = 0; i < max; i++) {
				var pb:PushButton = new PushButton(pageList, sx, sy, Number(i + 1).toString(), onPageClick);
				pb.toggle = true;
				pb.setSize(20, 20);
				
				pageClicks.push(pb);
			}
			if (max != total) {
				var arr:Array = new Array();
				for (var xx:Number = max + 1; xx < total+1; xx++) {
					arr.push(xx.toString());
				}
				edgeDrop = new ComboBox(pageList, sx, sy, "...", arr);
				edgeDrop.addEventListener(Event.SELECT, onEdgePageSelect);
				edgeDrop.openPosition = "top";
				edgeDrop.setSize(40, 20);
				pageClicks.push(edgeDrop);	
			}
			pageClicks[current - 1].selected = true;
			lastSelected = pageClicks[current - 1];
			lastSelected.enabled = false;
			pageList.x -= 20 * pageClicks.length;
			if (max != total) {
				pageList.x -= 20;
			}
		}
		private function onPopFilterChange(evt:Event):void {
			applyFilters();
			if(popFilter.selectedItem != "LATEST LISTING"){
				productCollection.sortByPrice(popFilter.selectedItem == "PRICE LOW - HIGH" ? "asc" : "desc");
			}else {
				productCollection.sortByDate();
			}
			pageList.visible = true;
			TweenMax.to(pageList, 1, { alpha:1, ease:Strong.easeInOut} );
		}
		private function createDetailedView(pvo:ProductVO):void {
			detailedView = new ProductDetailedView();
			detailedView.addEventListener(GenericEvent.CHANGE, onProductDetailChange);
			detailedView.thumbWidth = Math.ceil(env.getSetting("baseImageWidth") * env.getSetting("defaultImageScale"));
			detailedView.thumbHeight = Math.ceil(env.getSetting("baseImageHeight") * env.getSetting("defaultImageScale"));
			detailedView.x = displayGrid.x;
			detailedView.collection = productCollection;
			detailedView.product = pvo;
			detailedView.y = displayGrid.y;
			proxyGrid.detailGuide = detailedView;
			addChild(detailedView);
			TweenMax.to(pageList, 1, { alpha:0, ease:Strong.easeInOut, onComplete:function() { pageList.visible = false }} );
		}
		private function onProductDetailChange(evt:GenericEvent):void { ;
			if (detailedView) {
				proxyGrid.visible = true;
				removeChild(detailedView);
			}
			
			createDetailedView(evt.data as ProductVO);
		}
		private function createPreloader():void {
			preloader = new PreloadClip();
			preloader.x = Math.ceil(stage.stageWidth / 2);
			preloader.y = Math.ceil(stage.stageHeight / 2);
			addChild(preloader);
		}
		private function doneWaiting():void {
			if(fromWait){
				if (defaultSKU) {
					var defProduct:ProductVO = productCollection.getProductWithSKU(defaultSKU);
					if (defProduct) {
						setTimeout(createDetailedView, 200, defProduct);
					}
				}
				popFilter.visible = true;
				try{
					removeChild(preloader);
				}catch (e:Error) { };
				preloader = null;
				clearTimeout(pwait);
				fromWait = false;
			}
		}
		private function executeWaitingView():void {
			fromWait = true;
			clearTimeout(pwait);
			pwait = setTimeout(createPreloader, 100);
		}
		private function onItemClicked(evt:GenericEvent):void {
			createDetailedView(evt.data as ProductVO);
		}
		private function tooltipFollow(evt:MouseEvent):void {
			TweenLite.to(tooltip, .6, {alpha:1, x:mouseX, y:mouseY, ease:Strong.easeOut } );
		}
		private function onItemRolledOver(evt:GenericEvent):void {
			tooltip.visible = true;
			tooltip.setTexts(ProductVO(evt.data).brandName, ProductVO(evt.data).title, ProductVO(evt.data).price);
			stage.addEventListener(MouseEvent.MOUSE_MOVE, tooltipFollow);
		}
		private function onItemRolledOut(evt:GenericEvent):void {
			stage.removeEventListener(MouseEvent.MOUSE_MOVE, tooltipFollow);
			TweenLite.to(tooltip, 1, { alpha:0, ease:Strong.easeOut, onComplete:function() { tooltip.visible = false }} );
		}
		private function onDisplayGridGenerated(evt:GenericEvent):void {
			doneWaiting();
			createPages(displayGrid.currentPage, displayGrid.totalPages);
		}
		private function initializeComponent(evt:Event):void {
			productCollection = new FlipCollection();
			defaultSKU = loaderInfo.parameters.defaultSKU;
			createUIElements();
			createDataManagers();
		}
		private function applyFilters():void {
			if (!popFilter.visible) {
				popFilter.visible = true;
			}
			clearTimeout(chunkResume);
			chunk.pause();
			if (detailedView) {
				if (contains(detailedView)) {	
					removeChild(detailedView);
				}
			}
		}
		private function onApplyProductFilters(arr:Array):void {
			applyFilters();
			productCollection.applyFilterSet(arr);
		}
		private function onTestPageChange(evt:MouseEvent = null):void {
			displayGrid.nextPage();
		}
		private function onTestFilter(evt:MouseEvent = null):void {
			applyFilters();
			productCollection.clearFilters();
		}
	}
}